Skip to content

Release 3.6.0 to main - #307

Merged
5Amogh merged 159 commits into
mainfrom
release-3.6.0
Jan 7, 2026
Merged

Release 3.6.0 to main#307
5Amogh merged 159 commits into
mainfrom
release-3.6.0

Conversation

@5Amogh

@5Amogh 5Amogh commented Jan 7, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

Release Notes

  • New Features

    • Added feedback collection functionality for user experience improvement.
    • Added SMS notifications for prescription details.
    • Enhanced diagnosis search with infinite scrolling and pagination for faster access.
    • Implemented user interaction analytics across clinical forms.
    • Enhanced doctor signature management and verification capabilities.
    • Improved data synchronization status reporting with partial completion indicators.
  • Bug Fixes

    • Fixed user session data persistence for improved reliability.
    • Improved authentication flow and error handling.
  • Documentation

    • Added new feedback and authentication-related translations.
    • Updated configuration for analytics and tracking features.

✏️ Tip: You can customize this high-level summary in your review settings.

vanitha1822 and others added 30 commits July 9, 2025 12:09
Fix the URL correction for doctor update
* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

* fix: amm-1579

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
* fix: remove the additional slash in the url to fix the 404 issue

* fix: past obstetric history dropdown changes

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
fix: amm-1730 action buttons issue fix in chief complaints
* fix: disply error msg based on the response

* Revert "fix: disply error msg based on the response"

This reverts commit 6273191.

* fix for 1585, 1583 (#189)

* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>

* Amm-1579 (#192)

* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

* fix: amm-1579

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>

* fix: amm-1580

* fix: amm-1597

* fix: amm-1583

* fix: amm-1655

* Update version in pom.xml to 3.4.0

* Update pom.xml

* Update pom.xml

* Update pom.xml

* fix: show the message on token expiry (#200)

* fix: amm-1416 (#199)

* fix: refer resaon should disable initial (#203)

* AMM-1577 & AMM-1578 Menstrual History & Obstetric History changes (#204)

* fix: remove the additional slash in the url to fix the 404 issue

* fix: past obstetric history dropdown changes

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>

* fix: amm-1747 and amm-1583 (#208)

* fix: amm-1730 action buttons issue fix in chief complaints

---------

Co-authored-by: SnehaRH <sneha@navadhiti.com>
Co-authored-by: Amoghavarsh <93114621+5Amogh@users.noreply.github.com>
Co-authored-by: SnehaRH <77656297+snehar-nd@users.noreply.github.com>
Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
Co-authored-by: 5Amogh <amoghavarsh@navadhiti.com>
fix: amm-1668 beneficiary details addition
* fix: amm-1747 and amm-1583

* fix: amm-1595 lymphnodes are not patching

* fix: amm-1730 action buttons issue fix in chief complaints

* fix: provisonal diagnosis values patching issue

* fix: provisonal diagnosis values patching issue

---------

Co-authored-by: 5Amogh <amoghavarsh@navadhiti.com>
* fix: remove the additional slash in the url to fix the 404 issue

* fix: past obstetric history dropdown changes

* Release 3.4.0 (#1)

* fix: disply error msg based on the response

* Revert "fix: disply error msg based on the response"

This reverts commit 6273191.

* fix for 1585, 1583 (#189)

* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>

* Amm-1579 (#192)

* fix: amm-1584

* fix: amm-1583

* fix: amm-1589

* fix: code rabitt fixs

* fix: amm-1593

* fix: amm-1590 aam-1591

* fix: amm-1592

* fix: removed extra angle bracket

* fix: inventory redirection issue fixed

* fix: remove the additional slash in the url to fix the 404 issue

* fix: amm-1585 css fixes

* fix: amm-1583 facilityId was passing encrypted

* fix: amm-1579

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>

* fix: amm-1580

* fix: amm-1597

* fix: amm-1583

* fix: amm-1655

* Update version in pom.xml to 3.4.0

* Update pom.xml

* Update pom.xml

* Update pom.xml

* fix: show the message on token expiry (#200)

* fix: amm-1416 (#199)

* fix: refer resaon should disable initial (#203)

* AMM-1577 & AMM-1578 Menstrual History & Obstetric History changes (#204)

* fix: remove the additional slash in the url to fix the 404 issue

* fix: past obstetric history dropdown changes

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>

* fix: amm-1747 and amm-1583 (#208)

* fix: amm-1730 action buttons issue fix in chief complaints

---------

Co-authored-by: SnehaRH <sneha@navadhiti.com>
Co-authored-by: Amoghavarsh <93114621+5Amogh@users.noreply.github.com>
Co-authored-by: SnehaRH <77656297+snehar-nd@users.noreply.github.com>
Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
Co-authored-by: 5Amogh <amoghavarsh@navadhiti.com>

* fix(bug): ncd-care-diagnosis and provisional diagnosis doctor patch issue

---------

Co-authored-by: Vanitha <vanitha@navadhiti.com>
Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
Co-authored-by: SnehaRH <sneha@navadhiti.com>
Co-authored-by: Amoghavarsh <93114621+5Amogh@users.noreply.github.com>
Co-authored-by: SnehaRH <77656297+snehar-nd@users.noreply.github.com>
Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com>
Co-authored-by: 5Amogh <amoghavarsh@navadhiti.com>
* fix: provisonal diagnosis values patching issue

* fix: added confirmatory feild name

* fix: file upload issue, file displaying duplicate
snehar-nd and others added 24 commits November 17, 2025 11:13
Sn/3.5 - common ui changes
* fix: remove userid from the payload

* fix: update version in pom.xml
Fix the WASA Issue : IDOR Vulnerability  (#290)
Fix:1931 JWT expiry error handling
@coderabbitai

coderabbitai Bot commented Jan 7, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR introduces comprehensive user interaction tracking via AmritTrackingService across the application, implements a new SMS prescription notification feature, enhances diagnosis autocomplete with server-side pagination and lazy-loading, updates feedback and login navigation flows, modifies HTTP interceptor for platform-feedback requests, and extends environment configurations with tracking and SMS endpoints.

Changes

Cohort / File(s) Summary
Common-UI Submodule
Common-UI
Submodule pointer updated from bb57ecf to 93c9157, indicating upstream changes to the Common-UI library.
Version and CI Config
pom.xml, scripts/ci-prebuild.js
Version bumped from 3.4.0 to 3.6.0; CI environment variables added for tracking (SITE_ID, TRACKER_URL, TRACKING_PLATFORM, TRACKING_ENABLED).
Tracking Service Integration
src/app/app.component.ts, src/app/app-modules/core/components/app-footer/..., src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/..., src/app/app-modules/nurse-doctor/examination/.../..., src/app/app-modules/nurse-doctor/history/general-opd-history/past-history/..., src/app/app-modules/nurse-doctor/visit-details/.../..., src/app/app-modules/nurse-doctor/vitals/.../..., src/app/app-modules/registrar/registration/.../..., src/app/app-modules/service-point/service-point.component.ts
AmritTrackingService imported and injected across 25+ components; new trackFieldInteraction(fieldName) methods added; template event bindings (focus, selectionChange, click, change) wired to tracking calls for telemetry.
Diagnosis Autocomplete Pagination
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/general-opd-diagnosis/..., src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-care-diagnosis/..., src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-screening-diagnosis/..., src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.*
New AutocompleteScrollerDirective enables infinite-scroll pagination; per-index state arrays (pageByIndex, lastQueryByIndex, loadingMore, noMore) manage paginated fetches; bootstrap and fetchPage logic loads results incrementally; template bindings for panelReady and nearEnd events added.
SMS Notification Feature
src/app/app-modules/nurse-doctor/sms-notification/..., src/app/app-modules/nurse-doctor/smsTemplate/...
New SmsNotificationComponent with dialog UI for prescription SMS; SmsTemplateService provides endpoints for SMS templates and types; workarea component SMSObjectCreation and sendPrescriptionSms helpers trigger SMS workflows post-submission.
Feedback Navigation
src/app/app-modules/core/components/app-header/app-header.component.ts, src/app/app-modules/core/components/app-footer/app-footer.component.html, src/app/app-routing.module.ts
Logout navigation changed from /login to /feedback (sl=MMU); footer replaced right-aligned status with interactive Feedback block; new /feedback lazy-loaded route added.
HTTP Interceptor & Language
src/app/app-modules/core/services/http-interceptor.service.ts, src/app/app-modules/core/services/http-service.service.ts
Platform-feedback requests exempt from Authorization header; language state now persisted to localStorage; http-service constructor initializes language from localStorage.
Doctor Service & Signature
src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts, src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/...
doctorSignatureFlag parameter added to multiple visit submission methods; new downloadSign, getUserId, checkUsersignatureExist methods; doctor-diagnosis case-sheet now conditionally renders signature section and fetches user ID asynchronously.
Data Sync and Diagnosis Display
src/app/app-modules/data-sync/workarea/workarea.component.*, src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/pnc-diagnosis/...
Status mapping updated for partial/completed states in CSS classes; diagnosis form population logic refined to conditionally add rows and populate provisionalDiagnosis field.
Login & Session Management
src/app/app-modules/login/login.component.ts, src/app/app-modules/nurse-doctor/doctor-worklist/doctor-worklist.component.ts, src/app/app-modules/nurse-doctor/nurse-worklist/nurse-worklist.component.ts
AmritTrackingService integrated; trackingService.setUserId() called on successful login; beneficiary providerServiceMapID and currentServiceID stored in session; worklist error handlers check err.handled flag; phone number stored in session.
Utility & Module Config
src/app/app-modules/nurse-doctor/shared/utility/autocomplete-scroller.directive.ts, src/app/app-modules/nurse-doctor/shared/utility/general-utility.ts, src/app/app-modules/nurse-doctor/nurse-doctor.module.ts, src/app/app.module.ts
AutocompleteScrollerDirective created for infinite-scroll behavior; provisionalDiagnosis field validator set to required; SmsNotificationComponent and AutocompleteScrollerDirective declared in NurseDoctorModule; TrackingModule.forRoot() and MatChipsModule added to AppModule.
Service Configuration
src/app/app-modules/service-point/service-point-resolve.service.ts, src/app/app-modules/service-point/service-point.component.ts, src/app/app-modules/service-point/service-point.service.ts
userId removed from getServicePoints and getMMUDemographics calls; signatures simplified.
Environment Configurations
src/environments/environment.*.ts, src/environments/environment.ci.ts.template
Tracking object added (platform: matomo, siteId, trackerUrl, trackingPlatform, enabled) across dev/test/local/prod/ci environments; SMS endpoints (getSMStemplates_url, getSMStypes_url, sendSMS_url) and user endpoints (getUserId, checkUsersignExistUrl) added.
Localization
src/assets/English.json, src/assets/Hindi.json, src/assets/Assamese.json
platform_feedback section added with localized feedback UI strings; coreComponents extended with errorForDataSync and partialDataSync keys; extensive ABHA-related translations and corrections across all language files.

Sequence Diagrams

sequenceDiagram
    participant User
    participant Dialog as SMS Dialog
    participant Service as SmsTemplateService
    participant Backend
    
    User->>Dialog: Enters mobile number
    Dialog->>Service: Fetch SMS Types
    Service->>Backend: POST getSMStypes
    Backend-->>Service: SMS types list
    Service-->>Dialog: SMS types populated
    
    Dialog->>Service: Fetch SMS Templates
    Service->>Backend: POST getSMStemplates
    Backend-->>Service: Templates list
    Service-->>Dialog: Templates populated
    
    User->>Dialog: Click "Send SMS"
    Dialog->>Service: sendSMS(payload array)
    Service->>Backend: POST sendSMS
    Backend-->>Service: Success response
    Service-->>Dialog: Show success snackbar
    Dialog->>Dialog: Close dialog
Loading
sequenceDiagram
    participant User
    participant Input as Diagnosis Input
    participant Directive as AutocompleteScroller
    participant Component
    participant Service as MasterdataService
    
    User->>Input: Type diagnosis (3+ chars)
    Input->>Component: onDiagnosisInputKeyup
    Component->>Component: Initialize pagination state
    Component->>Component: fetchPage(index, false)
    Component->>Service: Query diagnosis data
    Service-->>Component: Initial results batch
    Component->>Component: suggestedDiagnosisList[i] = results
    Component-->>Input: Display options
    
    Directive->>Component: onPanelReady (panel opened)
    Component->>Component: bootstrapUntilScrollable
    loop Until scrollable or max pages
        Component->>Service: Fetch next page
        Service-->>Component: More results
        Component->>Component: Append & deduplicate
    end
    
    User->>Directive: Scroll near end (threshold 0.6)
    Directive->>Component: onAutoNearEnd
    Component->>Component: fetchPage(index, true)
    Component->>Service: Fetch append page
    Service-->>Component: Additional results
    Component->>Component: Merge with existing
    Component-->>Input: Update display
Loading
sequenceDiagram
    participant User
    participant AppHeader
    participant Router
    participant Feedback as FeedbackModule
    
    User->>AppHeader: Click logout
    AppHeader->>Router: navigate([/feedback], { queryParams: { sl: 'MMU' } })
    Router->>Feedback: Load feedback module lazily
    Feedback-->>Router: Module loaded
    Router-->>User: Display feedback component
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • added tracking throughout the MMU UI #217: Adds identical AmritTrackingService integration pattern with tracking imports, constructor injections, trackFieldInteraction methods, and environment tracking config across multiple components and localization updates.

Suggested reviewers

  • snehar-nd

Poem

🐰 Hop along, dear coder, the feedback path now shines,
With tracking breadcrumbs scattered across all the lines,
Diagnoses scroll lazy through pages of care,
SMS prescriptions float gently on air, 🧾✨
From login to sign, every moment's been traced!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Release 3.6.0 to main' directly describes the PR's intent: a version release from a release branch to the main branch. It matches the pom.xml version bump from 3.4.0 to 3.6.0 and the overall changeset scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom Pre-merge Checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

sonarqubecloud Bot commented Jan 7, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
24.5% Duplication on New Code (required ≤ 3%)
D Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (9)
src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/doctor-diagnosis-case-sheet.component.html (1)

1442-1451: Guard the Doctor's Sign section with a conditional to match the signature availability logic.

The section wrapper (line 1442) renders unconditionally, meaning the "Doctor's Sign:" label always displays even when no signature is available. The imgUrl is only populated when caseSheetData?.BeneficiaryData?.doctorSignatureFlag is true (lines 432-434), but this condition doesn't prevent the label from rendering.

Add a conditional guard to the wrapper:

<div class="row m-t-50" *ngIf="imgUrl">
  <div class="col-xs-6">&nbsp;</div>
  <div class="col-xs-6">
    <p>
      <strong> {{ currentLanguageSet?.casesheet?.docSign }}:</strong>
      &nbsp;&nbsp;
      <img [src]="imgUrl" alt="sign" *ngIf="imgUrl" />
    </p>
  </div>
</div>

This prevents the entire section from displaying when there's no signature, avoiding the confusing orphaned label.

scripts/ci-prebuild.js (2)

28-28: Add ejs to dependencies in package.json.

The script requires the ejs module but it's not declared in package.json. This will cause the script to fail in CI environments where dependencies aren't pre-installed.


25-28: Add ejs to package.json dependencies.

The ejs module is required in line 28 of this script but is not declared in package.json. Add it to the dependencies section to ensure proper package management and reproducibility:

"dependencies": {
  ...
  "ejs": "^3.1.7"
}
src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts (1)

952-1016: Add missing doctorSignatureFlag parameter to postDoctorCovidCareDetails method.

All other postDoctor*Details methods in this service include the doctorSignatureFlag parameter and add it to their payloads, but postDoctorCovidCareDetails omits it. The call site in workarea.component.ts also needs to be updated to pass this parameter.

Changes required

In doctor.service.ts method signature (lines 952–954):

 postDoctorCovidCareDetails(
   patientMedicalForm: any,
   otherDetails: any,
   tcRequest: any,
+  doctorSignatureFlag: any
 ) {

In the payload (before the return statement):

     createdBy: this.sessionstorage.getItem('userName'),
     tcRequest: tcRequest,
+    doctorSignatureFlag: doctorSignatureFlag,
   };

In workarea.component.ts call site:

 this.doctorService
   .postDoctorCovidCareDetails(
     this.patientMedicalForm,
     temp,
-    this.schedulerData
+    this.schedulerData,
+    this.doctorSignatureFlag
   )
src/app/app-modules/nurse-doctor/workarea/workarea.component.ts (1)

1073-1088: Critical: Double navigation when SMS is sent for Cancer Screening.

When prescribedDrugs.length > 0, both sendPrescriptionSms() (which navigates after dialog closes at lines 2511-2516) and the explicit router.navigate at lines 1084-1088 are executed. This causes immediate navigation followed by another navigation attempt when the dialog closes, leading to unpredictable behavior.

Other visit types correctly use an else branch to avoid this issue.

🔎 Proposed fix
               if (res.statusCode === 200 && res.data !== null) {
                 this.patientMedicalForm.reset();
-                this.confirmationService.alert(res.data.response, 'success');
                 if (prescribedDrugs.length > 0) {
                   const prescriptionSmsObject = this.SMSObjectCreation(
                     [],
                     prescribedDrugs,
                     res.data.prescribedDrugIDs
                   );
                   this.sendPrescriptionSms(prescriptionSmsObject);
-                }
-                if (this.isSpecialist) {
-                  this.router.navigate(['/common/tcspecialist-worklist']);
                 } else {
-                  this.router.navigate(['/nurse-doctor/doctor-worklist']);
+                  this.confirmationService.alert(res.data.response, 'success');
+                  if (this.isSpecialist) {
+                    this.router.navigate(['/common/tcspecialist-worklist']);
+                  } else {
+                    this.router.navigate(['/nurse-doctor/doctor-worklist']);
+                  }
                 }
               }
src/app/app-modules/service-point/service-point.component.html (1)

16-28: (selectionChange) event does not exist on mat-radio-group.

Angular Material's mat-radio-group emits a (change) event, not (selectionChange). The tracking call on line 19 will never fire. You should move the tracking call into the (change) handler or rename the event.

🔎 Proposed fix
              <mat-radio-group
                formControlName="sessionID"
-               (change)="filterVansList()"
-               (selectionChange)="trackFieldInteraction('Service Type')">
+               (change)="filterVansList(); trackFieldInteraction('Service Type')">
src/app/app-modules/nurse-doctor/nurse-doctor.module.ts (1)

169-169: Remove duplicate MatChipsModule import.

MatChipsModule appears twice in the imports array (lines 169 and 173). Remove the duplicate entry.

🔎 Proposed fix
    MatTableModule,
-   MatChipsModule,
    MatDatepickerModule,
    NgxPaginationModule,
    SharedModule,
    MatChipsModule,
    MatToolbarModule,

Also applies to: 173-173

src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-screening-diagnosis/ncd-screening-diagnosis.component.ts (1)

87-93: Potential memory leak: Subscription not unsubscribed.

The subscription to nurseService.enableProvisionalDiag$ is not stored or unsubscribed in ngOnDestroy. This can cause memory leaks if the component is destroyed while the observable is still active.

Proposed fix
+ import { Subscription } from 'rxjs';
  ...
  diagnosisSubscription: any;
+ private enableProvisionalDiagSub!: Subscription;
  ...
  ngOnInit() {
    console.log('caseRecordMode', this.caseRecordMode);
    console.log('doctorDiagnosis', this.doctorDiagnosis);
-   this.nurseService.enableProvisionalDiag$.subscribe(response => {
+   this.enableProvisionalDiagSub = this.nurseService.enableProvisionalDiag$.subscribe(response => {
      if (response) {
        this.enableProvisionalDiag = true;
      } else {
        this.enableProvisionalDiag = false;
      }
    });
  }
+ 
+ ngOnDestroy() {
+   this.enableProvisionalDiagSub?.unsubscribe();
+   this.diagnosisSubscription?.unsubscribe();
+ }
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-care-diagnosis/ncd-care-diagnosis.component.ts (1)

170-184: Critical bug: addDiagnosis() called inside loop causes incomplete row expansion.

The condition if (diagnosisArrayList.length < savedDiagnosisData.length) is checked inside the loop after patching each index. This is problematic because:

  1. On iteration i=1, if diagnosisArrayList.length is 1 and savedDiagnosisData.length is 3, it adds only one row
  2. On iteration i=2, diagnosisArrayList.at(2) may not exist yet, causing the patch to fail or target undefined

The rows should be expanded before the loop starts (as done correctly in ncd-screening-diagnosis.component.ts using a while loop).

Proposed fix
  patchProvisionalDiagnosisDetails(provisionalDiagnosis: any) {
    const savedDiagnosisData = provisionalDiagnosis;
    const diagnosisArrayList = this.generalDiagnosisForm.controls[
      'provisionalDiagnosisList'
    ] as FormArray;
    if (
      provisionalDiagnosis[0].term !== '' &&
      provisionalDiagnosis[0].conceptID !== ''
    ) {
+     // Expand array to fit all saved diagnoses BEFORE patching
+     while (diagnosisArrayList.length < savedDiagnosisData.length) {
+       this.addDiagnosis();
+     }
      for (let i = 0; i < savedDiagnosisData.length; i++) {
        diagnosisArrayList.at(i).patchValue({
          viewProvisionalDiagnosisProvided: savedDiagnosisData[i].term,
          term: savedDiagnosisData[i].term,
          conceptID: savedDiagnosisData[i].conceptID,
        });
        (<FormGroup>diagnosisArrayList.at(i)).controls[
          'viewProvisionalDiagnosisProvided'
        ].disable();
-
-       if (diagnosisArrayList.length < savedDiagnosisData.length) {
-         this.addDiagnosis();
-       }
      }
    }
  }
🤖 Fix all issues with AI agents
In @src/app/app-modules/core/services/http-service.service.ts:
- Around line 25-28: The constructor in HttpServiceService calls JSON.parse on
localStorage.getItem('appLanguage') without protecting against invalid JSON;
wrap the parse in a try/catch around the retrieval of
localStorage.getItem('appLanguage') inside the constructor, assign this.language
= null on parse failure (or when value is null), and log or remove the corrupted
key (e.g., console.error or localStorage.removeItem('appLanguage')) so service
initialization doesn't throw; reference the constructor,
localStorage.getItem('appLanguage'), JSON.parse, and this.language when making
the change.

In
@src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts:
- Around line 55-56: The code imports and likely uses AmritTrackingService to
track sensitive field-level interactions (ePHI); update FindingsComponent (and
any components using AmritTrackingService) to enforce a centralized
privacy-and-compliance gating layer: require explicit, recorded user consent
before enabling AmritTrackingService for health fields, consult/add a DPIA entry
for this processing, ensure audit events are stored via an encrypted,
access-controlled audit pipeline (encrypt at rest/in transit and use a
BA-approved vendor), apply pseudonymization/minimum-necessary transformations
before sending analytics (aggregate or role-scoped summaries where possible),
include retention and access details in the app privacy notice, and move these
checks into a shared tracking wrapper/service so components call a
consent-and-compliance-checked API rather than using AmritTrackingService
directly.

In
@src/app/app-modules/nurse-doctor/history/general-opd-history/past-history/past-history.component.html:
- Around line 99-100: The analytics tracking labels for duration and time-unit
fields are ambiguous because both Past Illness and Past Surgery use the same
labels; update the calls to trackFieldInteraction in the template (where
validateDuration(pastIllness) and similar handlers are used) to pass distinct
labels prefixed by section (e.g., "PastIllness: Duration", "PastIllness: Time
Period Unit" and analogous "PastSurgery: Duration", "PastSurgery: Time Period
Unit") so analytics can distinguish sections; ensure every occurrence referenced
in the diff (the trackFieldInteraction invocations around validateDuration and
the time unit select) is updated consistently.

In @src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html:
- Around line 643-645: The remove-button condition wrongly checks
diagnosis.get('provisionalDiagnosisList')?.disabled (a non-existent child
control); change it to reference the actual top-level FormArray's disabled state
instead (e.g., use the parent form or the provisionalDiagnosisList FormArray:
parentForm.get('provisionalDiagnosisList')?.disabled or
provisionalDiagnosisList?.disabled) while keeping the other checks (i !== 0 ||
...); note that each diagnosis FormGroup only has conceptID, term, and
provisionalDiagnosis, so do not attempt to access provisionalDiagnosisList from
diagnosis.

In
@src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.html:
- Line 48: The paginator is not wired to the table because the template uses
*ngFor over data.prescribedDrugs instead of a MatTableDataSource; replace the
direct *ngFor table with an Angular Material table bound to a MatTableDataSource
(e.g., create a dataSource = new
MatTableDataSource<any>(this.data.prescribedDrugs)), add
@ViewChild(MatPaginator) paginator!: MatPaginator, and in ngAfterViewInit assign
this.dataSource.paginator = this.paginator so the mat-paginator controls paging;
alternatively remove the mat-paginator if pagination is not required.

In
@src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.spec.ts:
- Around line 9-16: TestBed.configureTestingModule for SmsNotificationComponent
is missing required Angular Material modules, Forms/Common modules, and
providers; update the TestBed.configureTestingModule call to include imports:
MatDialogModule, MatToolbarModule, MatIconModule, MatPaginatorModule,
MatCheckboxModule, MatFormFieldModule, MatInputModule, MatButtonModule,
FormsModule, CommonModule, and add providers that supply mock implementations
for SmsTemplateService, ConfirmationService, HttpServiceService,
SessionStorageService plus provide MAT_DIALOG_DATA with a test object containing
a prescribedDrugs array; create simple spy objects or jasmine.createSpyObj for
these services and pass them in the providers array so fixture =
TestBed.createComponent(SmsNotificationComponent) and fixture.detectChanges()
can run without DI or template compilation errors.

In
@src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.ts:
- Line 22: The SmsNotificationComponent declares ngOnInit and ngDoCheck but does
not implement the corresponding interfaces; update the SmsNotificationComponent
class to implement OnInit and DoCheck and add the necessary imports from
@angular/core, ensure the class signature includes "implements OnInit, DoCheck"
and that the ngOnInit() and ngDoCheck() method signatures match the interface
contracts so AOT and style rules are satisfied.
- Around line 148-150: The dialog is being closed synchronously before the async
subscribe callbacks run; move this.dialogRef.close() into the subscribe's next
callback (and optionally into the error callback) so the dialog only closes
after the async SMS send completes and the success or error snackbar is shown;
locate the subscribe call in sms-notification.component (the call that sends SMS
and uses subscribe with next/error) and remove the top-level
this.dialogRef.close(), then invoke this.dialogRef.close() inside the subscribe
next handler (and call it or handle UI appropriately in the error handler).

In @src/app/app-modules/nurse-doctor/smsTemplate/sms-template.service.spec.ts:
- Around line 27-38: The TestBed setup for SmsTemplateService is missing
providers for its dependencies; update TestBed.configureTestingModule to provide
SmsTemplateService plus mocked providers for HttpClient and HttpServiceService
(e.g., supply a jasmine spy object for HttpClient methods used by
SmsTemplateService and a simple stub for HttpServiceService) so that
TestBed.inject(SmsTemplateService) resolves without NullInjectorError.

In
@src/app/app-modules/nurse-doctor/visit-details/visit-details/visit-details.component.html:
- Around line 87-89: The mat-select for pregnancyStatus is using [attr.readonly]
which has no effect; change the binding to use [disabled] so the control is
actually disabled when visitCategory is 'ANC'. Update the pregnancyStatus
<mat-select> to bind [disabled] to the expression
patientVisitDetailsForm.controls['visitCategory'].value === 'ANC' (or the local
visitCategory getter if present) so the field is properly disabled instead of
attempting to set a readonly attribute.

In
@src/app/app-modules/nurse-doctor/vitals/general-patient-vitals/general-patient-vitals.component.html:
- Around line 247-248: The validation in checkNurseRequirements() is too broad:
narrow the waist circumference check so it only runs when visitCategory === 'NCD
screening' AND benAge >= 30 (to match the template's [required]="benAge >= 30 &&
visitCategory === 'NCD screening'"); update the error label reference from
vitalsCancerscreening_QC.waistCircumference to the correct NCD screening field
name used elsewhere (e.g., vitalsNCDscreening_QC.waistCircumference or the
module's NCD-specific label) so the error message aligns with the NCD workflow.

In @src/app/app-modules/nurse-doctor/workarea/workarea.component.ts:
- Around line 3104-3118: The code is using the wrong form reference: replace
uses of this.patientVisitForm when building the provisionalDiagnosisList for SMS
with the patientCaseRecordForm instance (as done in
submitGeneralOPDDiagnosisForm) so you don't call .value on null; specifically,
obtain the FormArray value from the patientCaseRecordForm (the
generalDiagnosisForm.provisionalDiagnosisList) before calling SMSObjectCreation,
then pass that value into SMSObjectCreation and continue to call
sendPrescriptionSms with the resulting prescriptionSmsObject; update references
around SMSObjectCreation and ensure the local variable name matches the pattern
used elsewhere (e.g., patientCaseRecordForm) to avoid null pointer exceptions.

In @src/assets/Assamese.json:
- Around line 1724-1741: Several ABHA-related i18n keys
(enterMobileNumberToBeLinkedWithAbha, doYouWantToVerifyMobileOtpForAbha,
abhaCardAlreadyExists, enterABHANumber, enterABHAAddress, enterAadhaarNumber,
enterMobileNumber, enterCorrectAuthIdForAuthMode, abhaAddressFound,
searchAndDownloadAbha, abhaSearchMode, verifyAbha, issueInAbhaCard,
fileUploadedSuccessfully, verifyMobileOtp, enterMobileOtp, verify,
abhaNumberAlreadyWith) are still in English; replace each English value with the
appropriate Assamese translation so the UI is consistent, or if leaving them in
English is intentional for a staged rollout, add a clear TODO comment next to
each key indicating why and when the Assamese translations will be added. Ensure
you update the exact JSON entries for those keys (matching the key names above)
and keep JSON syntax valid.

In @src/assets/Hindi.json:
- Around line 1727-1745: Several ABHA-related localization entries (e.g.,
enterMobileNumberToBeLinkedWithAbha, doYouWantToVerifyMobileOtpForAbha,
abhaCardAlreadyExists, enterABHANumber, enterABHAAddress, enterAadhaarNumber,
enterMobileNumber, enterCorrectAuthIdForAuthMode, abhaAddressFound,
searchAndDownloadAbha, abhaSearchMode, verifyAbha, issueInAbhaCard,
fileUploadedSuccessfully, verifyMobileOtp, enterMobileOtp, verify,
abhaNumberAlreadyWith, enterTenDigitMobileNumber) currently contain English
values; replace each value with the correct Hindi (Devanagari) translation
matching the file’s existing style (for example
enterMobileNumberToBeLinkedWithAbha -> "ABHA से जोड़ने के लिए फोन नंबर दर्ज
करें", verify -> "सत्यापित करें") ensuring punctuation and capitalization follow
local conventions, and run a quick lint/validation of the JSON to confirm no
syntax changes were introduced.
🟡 Minor comments (14)
src/assets/English.json-14-14 (1)

14-14: Clarify the consent checkbox logic.

The text "Submit anonymously (if unchecked, we will store your user id for follow-up)" is confusing. If the checkbox is unchecked, the feedback should NOT be anonymous, so saying "Submit anonymously" when unchecked is contradictory.

Consider rephrasing to make the behavior clear, such as:

  • "Submit anonymously" (simpler checkbox label)
  • Or: "Do not store my user ID (submit anonymously)"
src/assets/Assamese.json-57-57 (1)

57-57: Remove the trailing 'e' character.

The Assamese translation has an English letter 'e' at the end: "মাহিলি পৰিয়াল আয়e". This appears to be a typo.

🔎 Suggested fix
-        "monthlyFamilyIncome": "মাহিলি পৰিয়াল আয়e",
+        "monthlyFamilyIncome": "মাহিলি পৰিয়াল আয়",
src/assets/English.json-1757-1757 (1)

1757-1757: Align the display text with the key name.

The key name is enterTenDigitMobileNumber, but the value only says "Enter mobile number" without specifying the 10-digit requirement. Users won't know the expected format.

🔎 Suggested fix
-    "enterTenDigitMobileNumber": "Enter mobile number"
+    "enterTenDigitMobileNumber": "Enter 10-digit mobile number"
src/app/app-modules/nurse-doctor/workarea/workarea.component.ts-263-269 (1)

263-269: Add error handling and subscription cleanup for signature check.

The subscription to checkUsersignatureExist lacks error handling. If the API call fails, the user won't be informed and doctorSignatureFlag will remain false silently. Additionally, this subscription should be stored and unsubscribed in ngOnDestroy to prevent potential memory leaks.

🔎 Proposed fix

Add a class property to store the subscription:

signatureCheckSubscription!: Subscription;

Then update the subscription:

-    this.doctorService
+    this.signatureCheckSubscription = this.doctorService
       .checkUsersignatureExist(this.sessionstorage.getItem('userID'))
       .subscribe((res: any) => {
         if (res.statusCode === 200 && res.data !== null) {
           this.doctorSignatureFlag = res.data.signStatus;
         }
-      });
+      },
+      (err: any) => {
+        console.error('Error checking user signature:', err);
+      });

And clean up in ngOnDestroy:

if (this.signatureCheckSubscription) this.signatureCheckSubscription.unsubscribe();
src/app/app-modules/nurse-doctor/visit-details/chief-complaints/chief-complaints.component.html-78-80 (1)

78-80: Suspicious selectionChange event on input field.

Line 79 binds (selectionChange) to an <input> element, but selectionChange is only fired by <mat-select> components, not standard inputs. This binding has no effect. If duration validation is needed on input changes, use the existing (input) handler on line 78 or consider (blur).

🔎 Suggested fix
               formControlName="duration"
               (input)="onInputDuration(complaint)"
-              (selectionChange)="validateDuration(complaint)"
               (focus)="trackFieldInteraction('Duration')" />
src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/doctor-diagnosis-case-sheet.component.ts-439-451 (1)

439-451: Missing error handling in getUserId subscription.

If getUserId() fails (e.g., network error), the error is silently swallowed and downloadSign won't proceed. Consider adding error handling to notify or fallback gracefully.

🔎 Proposed fix
  downloadSign() {
    this.getUserId().subscribe(
      userId => {
        const userIdToUse = this.beneficiaryDetails?.tCSpecialistUserID ?? userId;
        this.doctorService.downloadSign(userIdToUse).subscribe(
          (response: any) => {
            const blob = new Blob([response], { type: response.type });
            this.showSign(blob);
          },
          (err: any) => {
            console.error('Error downloading signature:', err);
          }
        );
      },
+     (err: any) => {
+       console.error('Error getting user ID:', err);
+     }
    );
  }
src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/doctor-diagnosis-case-sheet.component.ts-33-34 (1)

33-34: Remove unused import.

The get import from 'jquery' appears to be unused in this file.

🔎 Proposed fix
-import { get } from 'jquery';
-import { map, Observable } from 'rxjs';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
src/app/app-modules/data-sync/workarea/workarea.component.ts-94-95 (1)

94-95: Remove debug statements before production release.

console.clear() is particularly problematic as it clears the developer console, hiding potentially useful debugging information from other parts of the application. The console.log(res) is also debug logging that should be removed.

🔎 Proposed fix
  getDataSYNCGroup() {
    this.dataSyncService.getDataSYNCGroup().subscribe((res: any) => {
-      console.clear();
-      console.log(res);
      if (res.statusCode === 200) {
        this.syncTableGroupList = this.createSyncActivity(res.data);
        console.log('syncTableGroupList', this.syncTableGroupList);
      }
    });
  }
src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.css-74-76 (1)

74-76: Fix the margin property override.

Line 74 sets margin-top: 10px, but line 75 immediately overrides it with margin: 0, effectively nullifying the top margin. This appears unintentional.

🔎 Proposed fix
 .sms-section .alt-phone-field {
-  margin-top: 10px;
   margin: 0;
+  margin-top: 10px;
   width: 260px;
   min-width: 180px;
 }

Alternatively, if no top margin is needed:

 .sms-section .alt-phone-field {
-  margin-top: 10px;
   margin: 0;
   width: 260px;
   min-width: 180px;
 }

Committable suggestion skipped: line range outside the PR's diff.

src/app/app.component.ts-46-46 (1)

46-46: Remove or clarify the unused trackingService injection.

The trackingService is injected in the constructor but never used anywhere in the component or its template. Either remove this unused dependency or add a comment explaining why it's instantiated at the component level.

src/app/app-modules/nurse-doctor/case-record/general-case-record/test-and-radiology/test-and-radiology.component.html-72-74 (1)

72-74: Safe navigation operator removed - potential runtime error.

Line 73 changed from component?.testResultValue to component.testResultValue, removing the safe navigation operator. If component can be null or undefined, this will cause a runtime error.

Lines 85-87 and 102-104 retain the safe navigation operator (component?.testResultUnit, component?.remarks), suggesting defensive coding is still needed.

🔎 Proposed fix
 <div *ngFor="let component of element.componentList">
-  {{ component.testResultValue }}
+  {{ component?.testResultValue }}
 </div>
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/general-opd-diagnosis/general-opd-diagnosis.component.ts-180-181 (1)

180-181: Fix Prettier formatting issue causing CI failure.

The pipeline is failing due to an extra newline on line 181.

🔎 Proposed fix
   onDiagnosisInputKeyup(value: string, index: number) {
-
     const term = (value || '').trim();
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-screening-diagnosis/ncd-screening-diagnosis.component.ts-262-288 (1)

262-288: Potential runaway loop in bootstrapUntilScrollable.

The tryFill function uses requestAnimationFrame recursively without a guaranteed exit when loadingMore[rowIndex] remains true. If fetchPage errors out and doesn't reset loadingMore, this could spin indefinitely consuming CPU. Consider adding a timeout or maximum retry limit to the waiting logic.

Proposed fix with retry limit
  private bootstrapUntilScrollable(rowIndex: number, panelEl: HTMLElement) {
    let fetched = 0;
+   let waitFrames = 0;
+   const MAX_WAIT_FRAMES = 60; // ~1 second at 60fps

    const tryFill = () => {
      const scrollable = panelEl.scrollHeight > panelEl.clientHeight;
      if (
        scrollable ||
        this.noMore[rowIndex] ||
        fetched >= this.BOOTSTRAP_MAX_PAGES
      )
        return;

      if (this.loadingMore[rowIndex]) {
+       if (++waitFrames > MAX_WAIT_FRAMES) return; // prevent infinite wait
        requestAnimationFrame(tryFill);
        return;
      }

+     waitFrames = 0;
      fetched++;
      this.fetchPage(rowIndex, true);

      requestAnimationFrame(tryFill);
    };
src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.ts-112-126 (1)

112-126: Missing guard for empty prescribedDrugs array.

If this.data.prescribedDrugs is empty or undefined, the loop creates an empty req_arr, and calling sendSMS([]) might produce unexpected backend behavior. Consider validating upfront or disabling the send button when there are no drugs.

Proposed fix
  sendSMS() {
    const currentServiceID = this.sessionstorage.getItem('currentServiceID');
-   if (currentServiceID !== undefined) {
+   if (currentServiceID !== undefined && this.data.prescribedDrugs?.length > 0) {
      this._smsService
        .getSMStypes(currentServiceID)
        ...
+   } else if (!this.data.prescribedDrugs?.length) {
+     this.snackBar.open('No prescribed drugs to send', 'Close', {
+       duration: 3000,
+       verticalPosition: 'top',
+     });
    }
  }

Committable suggestion skipped: line range outside the PR's diff.

🧹 Nitpick comments (37)
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/pnc-diagnosis/pnc-diagnosis.component.ts (1)

271-272: Consider adding entries before the loop for clarity.

The conditional logic inside the loop works correctly but relies on adding exactly one entry per iteration. A clearer approach would be to add all needed entries upfront:

while (provisionalDiagnosisList.length < provisionalDiagnosisDataList.length) {
  this.addProvisionalDiagnosis();
}
for (let i = 0; i < provisionalDiagnosisDataList.length; i++) {
  provisionalDiagnosisList.at(i).patchValue({...});
  // ...
}

This makes the intent explicit and removes the dependency on per-iteration additions. However, since this pattern matches the confirmatory diagnosis logic (lines 289-292) and appears to be working correctly, this refactor is optional.

src/app/app-modules/nurse-doctor/history/general-opd-history/past-history/past-history.component.html (1)

15-18: Tracking event binding follows sensible patterns.

The tracking implementation appropriately uses:

  • focus events for text inputs (capturing when users begin data entry)
  • selectionChange events for dropdowns (capturing selection changes)
  • click events for buttons (capturing explicit actions)

This pattern is consistent and aligns with standard telemetry practices.

Also applies to: 52-54, 80-81, 99-100, 113-116, 135-138, 147-150, 191-194, 219-220, 238-239, 252-255, 274-277, 287-289

src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts (1)

2907-2917: Consider URL encoding for userName to prevent issues with special characters.

If userName contains special characters (spaces, &, ?, etc.), the URL may be malformed or cause unexpected behavior. Consider using encodeURIComponent:

🔎 Proposed fix
 getUserId(userName: any) {
-  return this.http.get(environment.getUserId + userName);
+  return this.http.get(environment.getUserId + encodeURIComponent(userName));
 }
src/app/app-modules/nurse-doctor/workarea/workarea.component.ts (3)

2486-2502: Add defensive check for array length mismatch in SMSObjectCreation.

The method assumes prescribedDrugIDs array has the same length as prescriptions. If the API returns fewer IDs than expected (due to partial failures or data inconsistency), accessing prescribedDrugIDs[index] could return undefined, leading to incomplete SMS data.

🔎 Proposed defensive check
  SMSObjectCreation(
    diagnosisList: any,
    prescriptions: any,
    prescribedDrugIDs: any
  ) {
+   if (prescribedDrugIDs?.length !== prescriptions?.length) {
+     console.warn('Prescription IDs count mismatch with prescribed drugs');
+   }
    return {
      diagnosisProvided: diagnosisList?.map((d: any) => d.term).join(', '),
      prescribedDrugs: prescriptions?.map((p: any, index: number) => ({
        beneficiaryRegID: this.beneficiaryRegID,
-       prescribedDrugID: prescribedDrugIDs[index],
+       prescribedDrugID: prescribedDrugIDs?.[index],
        drugName: p.drugName,
        dosage: `${p.dose} (${p.drugStrength})`,
        frequency: p.frequency,
        noOfDays: p.duration,
      })),
    };
  }

2504-2518: Consider showing a success confirmation after SMS dialog closes.

The sendPrescriptionSms method navigates immediately after the dialog closes without displaying a success confirmation to the user. Other code paths show confirmationService.alert with success messages. Consider adding confirmation feedback for consistency with user expectations.

🔎 Proposed enhancement
  sendPrescriptionSms(prescriptionSmsObject: any) {
    const dialogRef = this.mdDialog.open(SmsNotificationComponent, {
      width: '900px',
      disableClose: true,
      data: prescriptionSmsObject,
    });

    dialogRef.afterClosed().subscribe(result => {
+     this.confirmationService.alert(
+       this.currentLanguageSet.alerts.info.dataSaved || 'Data saved successfully',
+       'success'
+     );
      if (this.isSpecialist) {
        this.router.navigate(['/common/tcspecialist-worklist']);
      } else {
        this.router.navigate(['/nurse-doctor/doctor-worklist']);
      }
    });
  }

2868-2870: Remove unused variable declaration.

The patientVisitForm variable is declared but never used in submitCovidCareDiagnosisForm. This appears to be a copy-paste artifact from other methods that do use this variable for SMS creation.

🔎 Proposed fix
  submitCovidCareDiagnosisForm() {
    if (this.checkNurseRequirements(this.patientMedicalForm)) {
      const temp = {
        beneficiaryRegID: this.beneficiaryRegID,
        benVisitID: this.visitID,
        visitCode: this.sessionstorage.getItem('visitCode'),
        providerServiceMapID: this.sessionstorage.getItem('providerServiceID'),
        createdBy: this.sessionstorage.getItem('userName'),
      };

-     const patientVisitForm = <FormGroup>(
-       this.patientMedicalForm.controls['patientCaseRecordForm']
-     );
-
      this.doctorService
src/app/app-modules/login/login.component.ts (1)

158-163: Consider removing duplicate setUserId call.

The trackingService.setUserId is called here (line 158-160) and then again inside getServicesAuthdetails (line 258), which is invoked immediately after on line 161-163. While this doesn't cause incorrect behavior, the duplicate call is redundant.

🔎 Proposed fix to remove duplicate call
                              .subscribe((userLoggedIn: any) => {
                                if (userLoggedIn.statusCode === 200) {
                                  if (userLoggedIn?.data?.previlegeObj[0]) {
                                    this.sessionstorage.setItem(
                                      'loginDataResponse',
                                      JSON.stringify(userLoggedIn.data)
                                    );
-                                    this.trackingService.setUserId(
-                                      userLoggedIn.data.userID
-                                    );
                                    this.getServicesAuthdetails(
                                      userLoggedIn.data
                                    );
src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.html (2)

155-156: Missing focus tracking for Unit field.

The Unit field has selectionChange tracking on line 156 but appears to be missing (focus) tracking on line 155, unlike other select fields (e.g., Dosage on lines 93-94). Consider adding focus tracking for consistency:

🔎 Suggested addition
         name="unit"
         [(ngModel)]="currentPrescription.unit"
         [disabled]="!currentPrescription.drugID"
-        
+        (focus)="trackFieldInteraction('Unit')"
         (selectionChange)="trackFieldInteraction('Unit Selection')"
         required>

167-172: Use named constants to replace magic number form IDs.

The quantity field is conditionally hidden for formIDs 1 and 2 across multiple prescription components. This pattern appears intentional and consistent, but the magic numbers lack explanation. Replace formID !== 1 && formID !== 2 with named constants (e.g., LIQUID_FORM_ID, INJECTION_FORM_ID) or add an inline comment explaining which form types these IDs represent—for example:

<!-- Hide quantity for liquid/injection forms (formID 1-2) -->
*ngIf="
  currentPrescription.formID &&
  currentPrescription.formID !== 1 &&
  currentPrescription.formID !== 2
"

This pattern is replicated in quick-consult.component.html and prescribe-tm-medicine.component.html and should be consistent across all three.

src/app/app-modules/data-sync/workarea/workarea.component.html (1)

102-141: Consider extracting inline styles to the component stylesheet.

The footer legend uses inline styles for flex layout and margins. While functional, moving these to workarea.component.css would improve maintainability.

src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.ts (2)

174-183: Arrays accessed by index without initialization may cause issues.

The arrays loadingMore, noMore, wantMore, pageByIndex, lastQueryByIndex, and suggestedDiagnosisList are accessed by index in methods like fetchPage, but they're initialized as empty arrays. Accessing array[index] where index hasn't been set will return undefined. While JavaScript handles this gracefully, consider initializing these per-index when first accessed or using a default value pattern.


1302-1328: Potential performance concern with recursive requestAnimationFrame in bootstrapUntilScrollable.

When loadingMore[rowIndex] is true, tryFill schedules itself repeatedly via requestAnimationFrame until loading completes. While bounded by BOOTSTRAP_MAX_PAGES, this creates a tight loop polling the loading state. Consider using the complete callback in fetchPage to chain the next iteration instead.

src/app/app-modules/core/services/http-service.service.ts (1)

22-24: Consider consolidating the dual HttpClient injection.

The service injects HttpClient twice with different names (_http and http). Line 32 uses this.http while line 35 uses this._http. This creates inconsistency and confusion.

Consider using a single HttpClient instance throughout:

  constructor(
-   private _http: HttpClient,
-   private http: HttpClient
+   private http: HttpClient
  ) {

Then update line 35:

  getLanguage(url: string) {
-   return this._http.get(url);
+   return this.http.get(url);
  }

Also applies to: 32-32

src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.css (1)

21-22: Remove commented-out code.

The commented border-radius properties should either be uncommented if needed or removed to keep the codebase clean.

src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.html (1)

74-74: Add validation to disable Send SMS button.

The Send SMS button is always enabled, even when an alternate number is provided but invalid. Consider disabling the button when altNum is true and the phone number is invalid to prevent erroneous submissions.

🔎 Suggested fix
-<button mat-raised-button class="send-btn" (click)="sendSMS()">
+<button mat-raised-button class="send-btn" (click)="sendSMS()" [disabled]="altNum && phnNum.invalid">
   Send SMS
 </button>
src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts (1)

472-474: Add error handling for tracking failures.

The trackFieldInteraction method delegates to the tracking service without error handling. If the tracking service fails, it could potentially disrupt the user experience.

🔎 Proposed fix to add defensive error handling
 trackFieldInteraction(fieldName: string) {
-  this.trackingService.trackFieldInteraction(fieldName, 'Findings');
+  try {
+    this.trackingService.trackFieldInteraction(fieldName, 'Findings');
+  } catch (error) {
+    console.error('Tracking error:', error);
+    // Fail silently to avoid disrupting user experience
+  }
 }
src/app/app-modules/nurse-doctor/visit-details/visit-details/visit-details.component.ts (1)

295-297: Add error handling for tracking failures.

Similar to other components, consider adding defensive error handling to prevent tracking failures from affecting the user experience.

🔎 Proposed fix
 trackFieldInteraction(fieldName: string) {
-  this.trackingService.trackFieldInteraction(fieldName, 'Visit Details');
+  try {
+    this.trackingService.trackFieldInteraction(fieldName, 'Visit Details');
+  } catch (error) {
+    console.error('Tracking error:', error);
+  }
 }
src/app/app-modules/nurse-doctor/examination/general-opd-examination/systemic-examination/musculoskeletal-system/musculoskeletal-system.component.ts (1)

184-189: Add error handling for tracking failures.

Consider wrapping the tracking call in try-catch to prevent exceptions from disrupting the examination workflow.

🔎 Proposed fix
 trackFieldInteraction(fieldName: string) {
-  this.trackingService.trackFieldInteraction(
-    fieldName,
-    'Musculoskeletal System Examination'
-  );
+  try {
+    this.trackingService.trackFieldInteraction(
+      fieldName,
+      'Musculoskeletal System Examination'
+    );
+  } catch (error) {
+    console.error('Tracking error:', error);
+  }
 }
src/app/app-modules/nurse-doctor/examination/general-opd-examination/systemic-examination/central-nervous-system/central-nervous-system.component.html (1)

12-12: Consider debouncing focus events for better performance.

The template adds multiple (focus) event bindings that will fire every time a user focuses on a textarea. For frequently accessed forms, this could generate substantial tracking traffic.

Consider implementing debouncing in the component to limit the frequency of tracking calls:

import { debounceTime, Subject } from 'rxjs';

private trackingSubject = new Subject<{field: string, context: string}>();

ngOnInit() {
  this.trackingSubject
    .pipe(debounceTime(300))
    .subscribe(({field, context}) => {
      this.trackingService.trackFieldInteraction(field, context);
    });
}

trackFieldInteraction(fieldName: string) {
  this.trackingSubject.next({field: fieldName, context: 'Central Nervous System Examination'});
}

Also applies to: 36-36, 54-54, 72-72, 90-90, 108-108, 122-122, 146-146

src/app/app-modules/nurse-doctor/examination/general-opd-examination/systemic-examination/systemic-examination.component.ts (1)

143-148: Add error handling for tracking failures.

Consider defensive error handling to ensure tracking issues don't affect the examination workflow.

🔎 Proposed fix
 trackFieldInteraction(fieldName: string) {
-  this.trackingService.trackFieldInteraction(
-    fieldName,
-    'Systemic Examination'
-  );
+  try {
+    this.trackingService.trackFieldInteraction(
+      fieldName,
+      'Systemic Examination'
+    );
+  } catch (error) {
+    console.error('Tracking error:', error);
+  }
 }
src/app/app-modules/core/components/app-footer/app-footer.component.html (1)

33-35: Consider improving icon accessibility.

The mail icon could benefit from an aria-label for screen readers, especially since it's part of an interactive element.

🔎 Suggested improvement
-      <mat-icon style="vertical-align: top; font-size: medium; margin-right: 2%"
-        >mail</mat-icon
-      >
+      <mat-icon 
+        style="vertical-align: top; font-size: medium; margin-right: 2%"
+        aria-label="Feedback"
+        >mail</mat-icon
+      >
src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.html (4)

126-128: Consider extracting multi-statement event handler to component method.

The optionSelected event contains three semicolon-separated method calls. For better maintainability, consider extracting this into a single component method.

🔎 Suggested refactor

In the component TypeScript file, add:

onComplaintSelected(event: any, index: number) {
  this.filterComplaints(event, index);
  this.getSCTid(event, index);
  this.trackFieldInteraction('Chief Complaint Selection');
}

Then update the template:

             <mat-autocomplete
               #auto="matAutocomplete"
               [displayWith]="displayChiefComplaint"
-              (optionSelected)="
-                filterComplaints($event, i); getSCTid($event, i); trackFieldInteraction('Chief Complaint Selection')
-              ">
+              (optionSelected)="onComplaintSelected($event, i)">

180-180: Consider extracting multi-statement event handler to component method.

The selectionChange event contains two semicolon-separated method calls. For better maintainability, consider extracting this into a single component method.

🔎 Suggested refactor

In the component TypeScript file, add:

onUnitOfDurationChange(complaint: any) {
  this.validateDuration(complaint);
  this.trackFieldInteraction('Unit Of Duration');
}

Then update the template:

               <mat-select
                 class="input-full-width mat_label_fix"
                 name="unitOfDuration"
                 formControlName="unitOfDuration"
                 [disabled]="!complaint.value.duration"
-                (selectionChange)="validateDuration(complaint); trackFieldInteraction('Unit Of Duration')">
+                (selectionChange)="onUnitOfDurationChange(complaint)">

213-213: Consider extracting multi-statement event handler to component method.

The click event contains two semicolon-separated method calls. For consistency with other refactoring suggestions, consider extracting this into a single component method.

🔎 Suggested refactor

In the component TypeScript file, add:

onRemoveComplaint(index: number, complaint: any) {
  this.removeCheifComplaint(index, complaint);
  this.trackFieldInteraction('Remove Complaint Button');
}

Then update the template:

             <button
               mat-mini-fab
               [id]="'removeBtn' + i"
               *ngIf="i !== 0 || (i === 0 && complaint.touched)"
-              (click)="removeCheifComplaint(i, complaint); trackFieldInteraction('Remove Complaint Button')"
+              (click)="onRemoveComplaint(i, complaint)"
               color="warn"
               style="margin-right: 3px"
               class="mat_warn_circle">

224-224: Consider extracting multi-statement event handler to component method.

The click event contains two semicolon-separated method calls. For consistency with other refactoring suggestions, consider extracting this into a single component method.

🔎 Suggested refactor

In the component TypeScript file, add:

onAddComplaint() {
  this.addCheifComplaint();
  this.trackFieldInteraction('Add Complaint Button');
}

Then update the template:

             <button
               mat-mini-fab
               [id]="'addBtn' + i"
               *ngIf="isLast"
               [disabled]="checkComplaintFormValidity(complaint)"
-              (click)="addCheifComplaint(); trackFieldInteraction('Add Complaint Button')"
+              (click)="onAddComplaint()"
               color="primary"
               class="mat_blue_circle">
src/app/app-modules/nurse-doctor/examination/general-opd-examination/general-examination/general-examination.component.ts (1)

208-208: Minor style change: type annotation removed.

The type annotation for hideForANCAndQC was removed. This is acceptable as TypeScript infers the type from the initialization, but for consistency, you may want to verify whether your team's coding guidelines prefer explicit type annotations for class properties.

src/app/app-modules/nurse-doctor/smsTemplate/sms-template.service.ts (3)

33-36: Unused dependency injection: httpIntercept is never used.

HttpServiceService is injected but all HTTP calls use HttpClient directly. Either remove the unused injection or use httpIntercept if it provides custom interceptor logic (e.g., auth headers, error handling).

🔎 Suggested fix: Remove unused injection
 export class SmsTemplateService {
   constructor(
-    private httpIntercept: HttpServiceService,
     private http: HttpClient
   ) {}

Or, if HttpServiceService wraps HttpClient with interceptors, use it instead:

 export class SmsTemplateService {
   constructor(
-    private httpIntercept: HttpServiceService,
-    private http: HttpClient
+    private http: HttpServiceService
   ) {}

38-49: Potential code duplication: getSMStemplates and getSMSTemplates are nearly identical.

Both methods call the same endpoint. The only difference is that getSMStemplates accepts an optional smsTypeID. Consider consolidating:

🔎 Suggested consolidation
-  getSMStemplates(providerServiceMapID: any, smsTypeID?: any) {
+  getSMStemplates(providerServiceMapID: any, smsTypeID?: any): Observable<any> {
     return this.http.post(environment.getSMStemplates_url, {
       providerServiceMapID: providerServiceMapID,
       smsTemplateTypeID: smsTypeID ? smsTypeID : undefined,
     });
   }
-
-  getSMSTemplates(providerServiceMapID: any) {
-    return this.http.post(environment.getSMStemplates_url, {
-      providerServiceMapID: providerServiceMapID,
-    });
-  }
+  // getSMSTemplates can be replaced by getSMStemplates(providerServiceMapID) without the second arg

56-58: Consider adding explicit return type annotations.

The service methods implicitly return Observable<any>. Adding explicit types improves maintainability and IDE support.

import { Observable } from 'rxjs';

sendSMS(obj: any): Observable<any> {
  return this.http.post(environment.sendSMS_url, obj);
}
src/app/app-modules/nurse-doctor/shared/utility/autocomplete-scroller.directive.ts (2)

57-70: Address linter warning: remove non-null assertion on line 67.

While the assertion is logically safe (assigned on line 58), the linter flags it. A minor refactor eliminates the warning.

🔎 Suggested fix
         this.ngZone.runOutsideAngular(() => {
-          this.scrollListener = () => {
+          const listener = () => {
             if (panelEl.scrollHeight <= panelEl.clientHeight) return; // no overflow yet
             const ratio =
               (panelEl.scrollTop + panelEl.clientHeight) / panelEl.scrollHeight;
             if (ratio >= this.threshold) {
               // hop back into Angular so change detection works
               this.ngZone.run(() => this.nearEnd.emit());
             }
           };
-          panelEl.addEventListener('scroll', this.scrollListener!, {
+          this.scrollListener = listener;
+          panelEl.addEventListener('scroll', listener, {
             passive: true,
           });
         });

95-104: Consider documenting the fallback logic for panel resolution.

The getPanelEl method uses internal Material APIs via any cast, which may break on future Angular Material updates. A brief comment helps future maintainers understand the fragility.

   private getPanelEl(): HTMLElement | null {
-    // Newer Material exposes panel element
+    // Access internal MatAutocomplete panel element.
+    // NOTE: This relies on internal Angular Material APIs and may need
+    // adjustment after Material version upgrades.
     const anyAc = this.ac as any;
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/general-opd-diagnosis/general-opd-diagnosis.component.ts (1)

305-307: Consider adding user feedback for fetch errors.

Currently, errors are only logged to console. Users may not understand why results stop loading.

         error: () => {
           console.error('Error fetching diagnosis data');
+          // Optionally show a toast or set an error state
+          // this.confirmationService.alert('Failed to load diagnosis suggestions', 'error');
         },
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-screening-diagnosis/ncd-screening-diagnosis.component.ts (1)

290-342: Subscription in fetchPage is not tracked for cleanup.

Each call to fetchPage creates a new subscription to masterdataService.searchDiagnosisBasedOnPageNo that is not tracked. While the stale-query guard at line 306 helps, rapid navigation or component destruction could leave dangling subscriptions.

Consider tracking active subscriptions per index and canceling them on new requests or component destruction:

+ private fetchSubs: Subscription[] = [];
  ...
  private fetchPage(index: number, append = false) {
    const term = this.lastQueryByIndex[index];
    if (!term) return;
    ...
+   this.fetchSubs[index]?.unsubscribe();
-   this.masterdataService
+   this.fetchSubs[index] = this.masterdataService
      .searchDiagnosisBasedOnPageNo(termAtReq, pageAtReq)
      .subscribe({...});
  }
src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.ts (2)

153-160: Console log in production code.

The console.log('charCode', charCode) statement on line 155 should be removed before production release.

Proposed fix
  allowOnlyNumbers(event: KeyboardEvent) {
    const charCode = event.which ? event.which : event.keyCode;
-   console.log('charCode', charCode);

    if (charCode < 48 || charCode > 57) {
      event.preventDefault();
    }
  }

1-15: Unused import: ViewChild and MatPaginator.

ViewChild and MatPaginator are imported but not used in the component. Remove unused imports to keep the code clean.

Proposed fix
-import { Component, Inject, ViewChild } from '@angular/core';
+import { Component, DoCheck, Inject, OnInit } from '@angular/core';
...
-import { MatPaginator } from '@angular/material/paginator';
src/app/app-modules/nurse-doctor/case-record/general-case-record/diagnosis/ncd-care-diagnosis/ncd-care-diagnosis.component.ts (2)

260-279: Same subscription cleanup concerns apply here.

As noted in the review of ncd-screening-diagnosis.component.ts, the subscriptions in fetchPage are not tracked for cleanup. Consider applying the same fix pattern to track and cancel subscriptions on component destruction or when new requests supersede old ones.

Also applies to: 342-394


314-340: Same bootstrapUntilScrollable loop concern applies.

The recursive requestAnimationFrame pattern has the same potential for spinning indefinitely if loadingMore never resets. Consider adding the retry limit safeguard suggested for ncd-screening-diagnosis.component.ts.

Comment on lines +25 to +28
) {
const storedLang = localStorage.getItem('appLanguage');
this.language = storedLang ? JSON.parse(storedLang) : null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add error handling for localStorage JSON parsing.

The constructor parses localStorage.getItem('appLanguage') without error handling. If the stored value is corrupted or invalid JSON, this will throw an exception and break service initialization.

🔎 Proposed fix
  constructor(
    private _http: HttpClient,
    private http: HttpClient
  ) {
    const storedLang = localStorage.getItem('appLanguage');
-   this.language = storedLang ? JSON.parse(storedLang) : null;
+   try {
+     this.language = storedLang ? JSON.parse(storedLang) : null;
+   } catch (e) {
+     console.error('Failed to parse stored language, resetting', e);
+     this.language = null;
+     localStorage.removeItem('appLanguage');
+   }
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
) {
const storedLang = localStorage.getItem('appLanguage');
this.language = storedLang ? JSON.parse(storedLang) : null;
}
) {
const storedLang = localStorage.getItem('appLanguage');
try {
this.language = storedLang ? JSON.parse(storedLang) : null;
} catch (e) {
console.error('Failed to parse stored language, resetting', e);
this.language = null;
localStorage.removeItem('appLanguage');
}
}
🤖 Prompt for AI Agents
In @src/app/app-modules/core/services/http-service.service.ts around lines 25 -
28, The constructor in HttpServiceService calls JSON.parse on
localStorage.getItem('appLanguage') without protecting against invalid JSON;
wrap the parse in a try/catch around the retrieval of
localStorage.getItem('appLanguage') inside the constructor, assign this.language
= null on parse failure (or when value is null), and log or remove the corrupted
key (e.g., console.error or localStorage.removeItem('appLanguage')) so service
initialization doesn't throw; reference the constructor,
localStorage.getItem('appLanguage'), JSON.parse, and this.language when making
the change.

Comment on lines +55 to +56
import { AmritTrackingService } from 'Common-UI/src/tracking';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find and examine the AmritTrackingService
fd -t f "tracking" --extension ts | head -20

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

# Examine the findings.component.ts file to see what's being tracked
find . -name "findings.component.ts" -type f

Repository: PSMRI/MMU-UI

Length of output: 153


🏁 Script executed:

# Search for where AmritTrackingService is used in the codebase
rg "AmritTrackingService" -t ts --max-count 20

Repository: PSMRI/MMU-UI

Length of output: 7516


🏁 Script executed:

# Look for privacy-related configurations or consent mechanisms
rg -i "consent|privacy|gdpr|hipaa" -t ts --max-count 30

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

cat -n src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts | head -120

Repository: PSMRI/MMU-UI

Length of output: 4826


🏁 Script executed:

cat -n src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts | sed -n '50,60p'

Repository: PSMRI/MMU-UI

Length of output: 697


🏁 Script executed:

cat -n src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts | sed -n '100,110p'

Repository: PSMRI/MMU-UI

Length of output: 507


🏁 Script executed:

cat -n src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts | sed -n '468,478p'

Repository: PSMRI/MMU-UI

Length of output: 263


🏁 Script executed:

# Get total line count to understand file size
wc -l src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts

Repository: PSMRI/MMU-UI

Length of output: 155


🌐 Web query:

GDPR requirements for user interaction tracking in healthcare applications consent

💡 Result:

Short answer — key GDPR requirements when tracking user interactions in healthcare apps (analytics, behavioural/ad interaction tracking):

  1. Health data = special-category data — generally prohibited unless a condition in Article 9 applies (explicit consent is one such condition). [1]

  2. If you rely on consent for tracking that processes or infers health data, consent must be valid and “explicit”: freely given, specific, informed, unambiguous (affirmative opt‑in), withdrawable, and typically expressed by a clear statement (separate from other consents). Be careful: consent may be invalid if there is a clear imbalance of power. [2][3]

  3. Consider alternative Article 9 grounds before using consent (e.g., processing for provision of health care under Article 9(2)(h), public‑interest/ research grounds) — these have their own strict conditions and Member‑State rules. [1][3]

  4. DPIA / high‑risk assessment: tracking in health apps is likely to trigger a Data Protection Impact Assessment (systematic monitoring, special‑category data, profiling or large‑scale processing). Conduct a DPIA before processing and consult the supervisory authority if residual high risks remain. [4]

  5. Implement and document technical & organisational safeguards: data minimisation, purpose limitation, pseudonymisation/encryption, retention limits, secure processor contracts (if using third‑party analytics), user rights support (access, rectification, erasure, portability, withdraw consent), and transparent privacy notices (what is tracked, purposes, legal basis, retention, third parties). Keep records to demonstrate compliance. [4][5]

If you want, I can: (a) draft explicit‑consent UI text for an app analytics flow, (b) outline a DPIA checklist for your specific tracking features, or (c) check Member‑State rules that may further restrict health data processing.

Sources: GDPR Article 9 (processing of special categories). [1] ICO guidance on explicit consent and when consent is appropriate. [2] EDPB guidance/opinions on consent and “consent or pay” / imbalance of power concerns. [3] EU / supervisory‑authority guidance on DPIAs (Article 35). [4] ICO / EU guidance on DPIAs, transparency and safeguards. [5]

References:
[1] GDPR Article 9 — Processing of special categories of personal data.
[2] ICO: What are the conditions for processing special category data; when is consent appropriate.
[3] EDPB opinions/guidance on consent (explicit consent, imbalance of power; consent models).
[4] European Commission / EDPB guidance on DPIAs (Article 35).
[5] ICO / EU guidance on transparency, security and contractual obligations for processors.


🌐 Web query:

HIPAA compliance for user behavior tracking in EHR systems

💡 Result:

Short summary — key HIPAA requirements and practical steps for tracking user behavior in EHRs

Legal/technical requirements

  • Implement audit controls that record and examine activity in systems containing ePHI (HIPAA Security Rule §164.312(b)). Regularly review those logs. [1][4]
  • Enforce access controls and role-based access so only authorized users can view ePHI (§164.312(a)). Apply the Minimum Necessary principle when using behavior data. [1][4]
  • Treat any vendor or analytics provider that collects/hosts behavior logs as a business associate (BA) and have a BA agreement that limits uses/disclosures and requires safeguards. [1][4]
  • Protect logs as ePHI (confidentiality, integrity, availability): strong access restriction, encryption at rest/in transit, integrity checks, backup and retention policies. [1][4]

Operational best practices

  • Log user identity, timestamp, patient/record identifier (or a reversible pseudonym), action performed, source IP/device, and reason/context when feasible. Use risk analysis to decide exact fields and retention. [3][4]
  • Limit who can query or export logs; add separation-of-duties and justification/approval workflows for investigations. [3]
  • Automate alerting for anomalous access patterns (bulk access, off-hours, privileged-user spikes) and document investigation steps. [3]
  • Retain audit trails per your risk analysis and state law; ensure tamper-evidence and ability to produce logs for investigations and breach response. [1][3]

Privacy risk reduction

  • Use pseudonymization or de‑identification of behavior data for analytics when individual-level identity is not required. Maintain re‑identification controls when pseudonyms are reversible. [1]
  • Apply Minimum Necessary: restrict behavioral reporting to role-appropriate summaries or aggregated metrics unless a specific clinical/administrative need exists. [1]

Third parties, cloud, and analytics vendors

  • Require BA agreements that: (a) prohibit uses beyond permitted healthcare operations; (b) require security safeguards, logging, breach notification; (c) allow audits/assessments. Limit downstream sharing. [1]
  • Verify vendor security posture (encryption, logging, SOC reports, vulnerability testing). Recent HHS proposals increase vendor oversight and require stronger controls (MFA, inventories, annual audits) — plan to adopt these controls. [2]

Emerging rulemaking (important to watch)

  • HHS proposed updates to the Security Rule (NPRM Jan 2025) that would tighten requirements (mandatory inventories, MFA, encryption, annual audits, stricter access-termination timelines). If finalized, these will affect logging and monitoring programs — monitor HHS/OCR rulemaking and implement early where possible. [2]

Practical checklist (implementation)

  • Record required audit fields; protect logs with encryption and strict access control. [3][4]
  • Define retention and review cadence in policy; perform periodic and post-incident reviews. [1][3]
  • Put BA agreements and vendor assessments in place. [1]
  • Apply Minimum Necessary and pseudonymize for analytics. [1]

If you want, I can:

  • draft an audit-log schema for your EHR (fields, retention, risk-mapping), or
  • create a short vendor-BA checklist you can use in procurement.

Sources

  1. HHS HIPAA Audit Protocol / Audit Controls & Access Control guidance. [HHS]. [4]
  2. Reuters summary of HHS Jan 6, 2025 NPRM to update the HIPAA Security Rule. [2]
  3. Research on using EHR audit logs and recommended log fields/practices (PubMed/PMC). [3]
  4. HHS OIG report on OCR HIPAA audit program (recommendations on audit/enforcement). [1]

Verify privacy and compliance mechanisms are in place for field-level user interaction tracking.

AmritTrackingService tracks field-level interactions on sensitive health data (chief complaints, diagnoses, examination findings). Ensure:

  • GDPR compliance: Explicit, freely-given, informed consent (separate from general app terms) is required before tracking health data. A Data Protection Impact Assessment (DPIA) should document the processing. Consent cannot be conditional on app access.
  • HIPAA compliance: Audit controls must record all interactions with ePHI. Any vendor handling logs must be a Business Associate with a signed BA agreement. Logs must be encrypted at rest and in transit. Apply the Minimum Necessary principle—use pseudonymization for analytics where individual identity is not required.
  • Privacy notice: A transparent privacy notice must disclose what data is tracked, for what purposes, retention periods, and which parties have access.
  • Data minimization: Confirm only necessary field-level data is collected; consider tracking aggregated metrics or role-appropriate summaries instead of individual interactions.

Note: This applies across multiple components. Consider addressing tracking compliance at the application level rather than component-by-component.

Also applies to: 104-104, 472-474

🤖 Prompt for AI Agents
In
@src/app/app-modules/nurse-doctor/case-record/general-case-record/findings/findings.component.ts
around lines 55 - 56, The code imports and likely uses AmritTrackingService to
track sensitive field-level interactions (ePHI); update FindingsComponent (and
any components using AmritTrackingService) to enforce a centralized
privacy-and-compliance gating layer: require explicit, recorded user consent
before enabling AmritTrackingService for health fields, consult/add a DPIA entry
for this processing, ensure audit events are stored via an encrypted,
access-controlled audit pipeline (encrypt at rest/in transit and use a
BA-approved vendor), apply pseudonymization/minimum-necessary transformations
before sending analytics (aggregate or role-scoped summaries where possible),
include retention and access details in the app privacy notice, and move these
checks into a shared tracking wrapper/service so components call a
consent-and-compliance-checked API rather than using AmritTrackingService
directly.

Comment on lines +99 to +100
(change)="validateDuration(pastIllness)"
(focus)="trackFieldInteraction('Duration')" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Disambiguate tracking labels for illness vs surgery fields.

The tracking labels 'Duration' (lines 100, 239) and 'Time Period Unit' (lines 115, 254) are used in both the Past Illness and Past Surgery sections, making it impossible to distinguish which section the user interacted with in analytics data.

🔎 Suggested fix: Use prefixed labels
 formControlName="timePeriodAgo"
 (change)="validateDuration(pastIllness)"
-(focus)="trackFieldInteraction('Duration')" />
+(focus)="trackFieldInteraction('Past Illness Duration')" />
 (selectionChange)="
   validateDuration(pastIllness);
-  trackFieldInteraction('Time Period Unit')
+  trackFieldInteraction('Past Illness Time Period Unit')
 ">
 formControlName="timePeriodAgo"
 (change)="validateDuration(pastSurgery)"
-(focus)="trackFieldInteraction('Duration')" />
+(focus)="trackFieldInteraction('Past Surgery Duration')" />
 (selectionChange)="
   validateDuration(pastSurgery);
-  trackFieldInteraction('Time Period Unit')
+  trackFieldInteraction('Past Surgery Time Period Unit')
 ">

Also applies to: 113-116, 238-239, 252-255

🤖 Prompt for AI Agents
In
@src/app/app-modules/nurse-doctor/history/general-opd-history/past-history/past-history.component.html
around lines 99 - 100, The analytics tracking labels for duration and time-unit
fields are ambiguous because both Past Illness and Past Surgery use the same
labels; update the calls to trackFieldInteraction in the template (where
validateDuration(pastIllness) and similar handlers are used) to pass distinct
labels prefixed by section (e.g., "PastIllness: Duration", "PastIllness: Time
Period Unit" and analogous "PastSurgery: Duration", "PastSurgery: Time Period
Unit") so analytics can distinguish sections; ensure every occurrence referenced
in the diff (the trackFieldInteraction invocations around validateDuration and
the time unit select) is updated consistently.

Comment on lines +643 to +645
*ngIf="
diagnosis.get('provisionalDiagnosisList')?.disabled ||
i !== 0 ||

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for diagnosis form group initialization and provisionalDiagnosisList references
rg -n "provisionalDiagnosisList" --type ts -B 5 -A 5 src/app/app-modules/nurse-doctor/quick-consult/

Repository: PSMRI/MMU-UI

Length of output: 6686


🏁 Script executed:

#!/bin/bash
# Also search for where the diagnosis form group is created/initialized
rg -n "new FormGroup|new FormArray" --type ts -B 3 -A 10 src/app/app-modules/nurse-doctor/quick-consult/ | head -100

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for the component file to understand the structure
find src/app/app-modules/nurse-doctor/quick-consult -name "*.ts" -type f

Repository: PSMRI/MMU-UI

Length of output: 208


🏁 Script executed:

#!/bin/bash
# Find where initProvisionalDiagnosisList is defined
rg -n "initProvisionalDiagnosisList" --type ts -B 2 -A 15 src/

Repository: PSMRI/MMU-UI

Length of output: 45415


🏁 Script executed:

#!/bin/bash
# Look at the quick-consult component HTML around lines 643-645 for more context
sed -n '630,660p' src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html

Repository: PSMRI/MMU-UI

Length of output: 1404


Fix the condition logic on the remove button.

The condition diagnosis.get('provisionalDiagnosisList')?.disabled attempts to access a control named provisionalDiagnosisList within the individual diagnosis form group, but this control does not exist. The individual diagnosis form group only contains conceptID, term, and provisionalDiagnosis controls. The provisionalDiagnosisList is a top-level FormArray in the parent form, not a nested control within each diagnosis group. This condition needs to be corrected to reference the actual controls available in the diagnosis form group.

🤖 Prompt for AI Agents
In @src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html
around lines 643 - 645, The remove-button condition wrongly checks
diagnosis.get('provisionalDiagnosisList')?.disabled (a non-existent child
control); change it to reference the actual top-level FormArray's disabled state
instead (e.g., use the parent form or the provisionalDiagnosisList FormArray:
parentForm.get('provisionalDiagnosisList')?.disabled or
provisionalDiagnosisList?.disabled) while keeping the other checks (i !== 0 ||
...); note that each diagnosis FormGroup only has conceptID, term, and
provisionalDiagnosis, so do not attempt to access provisionalDiagnosisList from
diagnosis.

</div>

<!-- Pagination -->
<mat-paginator [pageSize]="5" [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons></mat-paginator>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Paginator not connected to table data.

The mat-paginator is defined but the prescription table uses *ngFor directly on data.prescribedDrugs without a MatTableDataSource. The paginator will render but won't actually paginate the table. To fix this, either:

  1. Remove the paginator if not needed, or
  2. Bind the table to a MatTableDataSource and connect it to the paginator.
🔎 Example fix to wire the paginator

In the component TypeScript file, create a data source:

dataSource = new MatTableDataSource<any>(this.data.prescribedDrugs);
@ViewChild(MatPaginator) paginator!: MatPaginator;

ngAfterViewInit() {
  this.dataSource.paginator = this.paginator;
}

Then update the template to use mat-table instead of HTML table:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z4">
  <!-- columns definition -->
</table>
🤖 Prompt for AI Agents
In
@src/app/app-modules/nurse-doctor/sms-notification/sms-notification.component.html
at line 48, The paginator is not wired to the table because the template uses
*ngFor over data.prescribedDrugs instead of a MatTableDataSource; replace the
direct *ngFor table with an Angular Material table bound to a MatTableDataSource
(e.g., create a dataSource = new
MatTableDataSource<any>(this.data.prescribedDrugs)), add
@ViewChild(MatPaginator) paginator!: MatPaginator, and in ngAfterViewInit assign
this.dataSource.paginator = this.paginator so the mat-paginator controls paging;
alternatively remove the mat-paginator if pagination is not required.

Comment on lines +696 to +697
[disabled]="rbsResultChange()"
(focus)="trackFieldInteraction('RBS Test Result')" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for rbsResultChange implementation in cancer-patient-vitals component
fd 'cancer-patient-vitals.component.ts' -type f | head -5

Repository: PSMRI/MMU-UI

Length of output: 226


🏁 Script executed:

#!/bin/bash
# Get the implementation of rbsResultChange
rg -nP -A15 'rbsResultChange\s*\(' src/app/app-modules/nurse-doctor/vitals/cancer-patient-vitals/ --type=ts

Repository: PSMRI/MMU-UI

Length of output: 4189


🏁 Script executed:

#!/bin/bash
# Check the HTML file to verify lines 696-697 and 725-726
wc -l src/app/app-modules/nurse-doctor/vitals/cancer-patient-vitals/cancer-patient-vitals.component.html

Repository: PSMRI/MMU-UI

Length of output: 158


🏁 Script executed:

#!/bin/bash
# Get the complete rbsResultChange method
rg -nP -A30 'rbsResultChange\s*\(\)\s*:\s*boolean' src/app/app-modules/nurse-doctor/vitals/cancer-patient-vitals/cancer-patient-vitals.component.ts

Repository: PSMRI/MMU-UI

Length of output: 1361


🏁 Script executed:

#!/bin/bash
# Check the HTML lines mentioned in the review
sed -n '690,700p' src/app/app-modules/nurse-doctor/vitals/cancer-patient-vitals/cancer-patient-vitals.component.html
sed -n '720,730p' src/app/app-modules/nurse-doctor/vitals/cancer-patient-vitals/cancer-patient-vitals.component.html

Repository: PSMRI/MMU-UI

Length of output: 861


Remove the rbsResultChange() call from the [disabled] binding.

The rbsResultChange() method has side effects—it modifies service state via setRbsInCurrentVitals() and manipulates form control state (enable()/disable()). Calling it in a template binding causes these side effects to execute on every change detection cycle, which violates Angular best practices and can cause unexpected behavior.

Refactor to use a boolean property that's updated when the form value changes, or call rbsResultChange() in a component lifecycle hook or event handler instead of the template binding.

Also applies to: 725-726

Comment on lines +247 to +248
(focus)="trackFieldInteraction('Waist Circumference')"
[required]="benAge >= 30 && visitCategory === 'NCD screening'" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify validation error handling for required waist circumference field
rg -n "waistCircumference" --type=ts -g "*general-patient-vitals.component.ts" -A 5 -B 5

Repository: PSMRI/MMU-UI

Length of output: 7622


🏁 Script executed:

#!/bin/bash
# Check context around validation error handling
rg -n "checkNurseRequirements|required\.push" --type=ts -g "*general-patient-vitals.component.ts" -A 2 -B 2 | head -100

Repository: PSMRI/MMU-UI

Length of output: 11995


🏁 Script executed:

#!/bin/bash
# Check if there's any age-based condition for waistCircumference validation
rg -n "benAge.*waistCircumference|waistCircumference.*benAge" --type=ts -g "*general-patient-vitals.component.ts"

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check the validation setter/validation logic for waistCircumference field
rg -n "setValidators|updateValueAndValidity" --type=ts -g "*general-patient-vitals.component.ts" -A 3 -B 3 | grep -A 5 -B 5 "waistCircumference"

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check the specific lines in the HTML file where the required attribute is set
sed -n '240,255p' src/app/app-modules/nurse-doctor/vitals/general-patient-vitals/general-patient-vitals.component.html

Repository: PSMRI/MMU-UI

Length of output: 776


🏁 Script executed:

#!/bin/bash
# Check form initialization and validator setup for waistCircumference
rg -n "waistCircumference_cm.*Validators|patientVitalsForm.*waistCircumference" --type=ts -g "*general-patient-vitals.component.ts" -B 2 -A 2

Repository: PSMRI/MMU-UI

Length of output: 683


🏁 Script executed:

#!/bin/bash
# Check for any conditional validator logic based on age or visitCategory
rg -n "benAge|visitCategory.*waist" --type=ts -g "*general-patient-vitals.component.ts" -B 3 -A 3

Repository: PSMRI/MMU-UI

Length of output: 5047


🏁 Script executed:

#!/bin/bash
# Look for form control initialization to understand how validators are applied
rg -n "formGroup.*waistCircumference|patchValue.*waistCircumference|setValue.*waistCircumference" --type=ts -g "*general-patient-vitals.component.ts" -B 5 -A 5

Repository: PSMRI/MMU-UI

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check the checkIDRSForWaist method to understand age-based logic
rg -n "checkIDRSForWaist" --type=ts -g "*general-patient-vitals.component.ts" -A 10

Repository: PSMRI/MMU-UI

Length of output: 1494


🏁 Script executed:

#!/bin/bash
# Search for any documentation or comments about NCD screening age requirements
rg -n "NCD.*screening|age.*30|waist.*requirement" --type=ts --type=html -g "*general-patient-vitals*" -i -B 2 -A 2 | head -50

Repository: PSMRI/MMU-UI

Length of output: 6261


🏁 Script executed:

#!/bin/bash
# Check if there's any README or documentation about NCD screening requirements
find . -type f \( -name "README*" -o -name "*.md" \) -exec grep -l "NCD\|screening" {} \;

Repository: PSMRI/MMU-UI

Length of output: 38


Fix validation logic gap for age-conditional waist circumference requirement.

The [required] attribute in HTML (line 248) applies only when benAge >= 30 && visitCategory === 'NCD screening', but the validation in checkNurseRequirements() (lines 296-301 in component.ts) checks for waist circumference errors whenever visitCategory === 'NCD screening' without the age condition. This creates a mismatch: patients under 30 in NCD screening won't see the field as required but validation errors may still be enforced. Update checkNurseRequirements() to include the benAge >= 30 condition, or clarify if waist circumference should be mandatory for all NCD screening patients regardless of age. Additionally, the validation error message references vitalsCancerscreening_QC.waistCircumference which appears to be from a different screening context—ensure the error message label aligns with NCD screening workflows.

🤖 Prompt for AI Agents
In
@src/app/app-modules/nurse-doctor/vitals/general-patient-vitals/general-patient-vitals.component.html
around lines 247 - 248, The validation in checkNurseRequirements() is too broad:
narrow the waist circumference check so it only runs when visitCategory === 'NCD
screening' AND benAge >= 30 (to match the template's [required]="benAge >= 30 &&
visitCategory === 'NCD screening'"); update the error label reference from
vitalsCancerscreening_QC.waistCircumference to the correct NCD screening field
name used elsewhere (e.g., vitalsNCDscreening_QC.waistCircumference or the
module's NCD-specific label) so the error message aligns with the NCD workflow.

Comment on lines +3104 to +3118
if (prescribedDrugs.length > 0) {
const prescriptionSmsObject = this.SMSObjectCreation(
JSON.parse(
JSON.stringify(
(
this.patientVisitForm.get(
'generalDiagnosisForm.provisionalDiagnosisList'
) as FormArray
).value
)
),
prescribedDrugs,
res.data.prescribedDrugIDs
);
this.sendPrescriptionSms(prescriptionSmsObject);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Wrong form reference causes null pointer exception in PNC SMS flow.

At line 3109, this.patientVisitForm is used to access generalDiagnosisForm.provisionalDiagnosisList, but this.patientVisitForm refers to patientVisitForm (visit details), not patientCaseRecordForm (which contains the diagnosis forms). This will cause a runtime error when .value is accessed on null.

Compare with submitGeneralOPDDiagnosisForm (lines 3031-3033) which correctly creates a local reference to patientCaseRecordForm.

🔎 Proposed fix
  submitPNCDiagnosisForm() {
    if (this.checkNurseRequirements(this.patientMedicalForm)) {
      const temp = {
        beneficiaryRegID: this.beneficiaryRegID,
        benVisitID: this.visitID,
        visitCode: this.sessionstorage.getItem('visitCode'),
        providerServiceMapID: this.sessionstorage.getItem('providerServiceID'),
        createdBy: this.sessionstorage.getItem('userName'),
      };

+     const patientCaseRecordForm = <FormGroup>(
+       this.patientMedicalForm.controls['patientCaseRecordForm']
+     );
+
      const prescribedDrugs = this.getLabandPrescriptionData();
      this.doctorService
        .postDoctorPNCDetails(
          this.patientMedicalForm,
          temp,
          this.schedulerData,
          this.doctorSignatureFlag
        )
        .subscribe(
          (res: any) => {
            if (res.statusCode === 200 && res.data !== null) {
              this.patientMedicalForm.reset();
              this.removeBeneficiaryDataForDoctorVisit();
              if (prescribedDrugs.length > 0) {
                const prescriptionSmsObject = this.SMSObjectCreation(
                  JSON.parse(
                    JSON.stringify(
                      (
-                       this.patientVisitForm.get(
+                       patientCaseRecordForm.get(
                          'generalDiagnosisForm.provisionalDiagnosisList'
                        ) as FormArray
                      ).value
                    )
                  ),
                  prescribedDrugs,
                  res.data.prescribedDrugIDs
                );
                this.sendPrescriptionSms(prescriptionSmsObject);
              } else {
🤖 Prompt for AI Agents
In @src/app/app-modules/nurse-doctor/workarea/workarea.component.ts around lines
3104 - 3118, The code is using the wrong form reference: replace uses of
this.patientVisitForm when building the provisionalDiagnosisList for SMS with
the patientCaseRecordForm instance (as done in submitGeneralOPDDiagnosisForm) so
you don't call .value on null; specifically, obtain the FormArray value from the
patientCaseRecordForm (the generalDiagnosisForm.provisionalDiagnosisList) before
calling SMSObjectCreation, then pass that value into SMSObjectCreation and
continue to call sendPrescriptionSms with the resulting prescriptionSmsObject;
update references around SMSObjectCreation and ensure the local variable name
matches the pattern used elsewhere (e.g., patientCaseRecordForm) to avoid null
pointer exceptions.

Comment thread src/assets/Assamese.json
Comment on lines +1724 to +1741
"enterMobileNumberToBeLinkedWithAbha": "Enter Phone number to be linked with ABHA",
"doYouWantToVerifyMobileOtpForAbha": "Your provided mobile number is not linked with Aadhaar, Do you want to verify it?",
"abhaCardAlreadyExists": "ABHA already exists for the Aadhaar Number",
"enterABHANumber": "Please Enter ABHA Number",
"enterABHAAddress": "Please Enter ABHA Address",
"enterAadhaarNumber": "Please Enter Aadhaar Number",
"enterMobileNumber": "Please Enter Mobile Number",
"enterCorrectAuthIdForAuthMode": "Please Enter correct Authentication ID for choosen AuthMode",
"abhaAddressFound" : "ABHA Address Found:",
"searchAndDownloadAbha": "Search and Download ABHA",
"abhaSearchMode": "ABHA Search Mode*",
"verifyAbha": "Verify ABHA",
"issueInAbhaCard": "Issue in printing ABHA Card",
"fileUploadedSuccessfully": "File Uploaded successfully",
"verifyMobileOtp": "Verify Mobile OTP",
"enterMobileOtp": "Enter Mobile OTP",
"verify": "Verify",
"abhaNumberAlreadyWith": "The Abha number is already linked with beneficiary ID - ",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Complete the ABHA-related Assamese translations.

These 18 ABHA keys are showing English text instead of Assamese translations. This creates an inconsistent experience for Assamese-speaking users when they interact with ABHA features.

If this is intentional for a phased rollout, please add a TODO comment. Otherwise, these strings should be translated before release.

🤖 Prompt for AI Agents
In @src/assets/Assamese.json around lines 1724 - 1741, Several ABHA-related i18n
keys (enterMobileNumberToBeLinkedWithAbha, doYouWantToVerifyMobileOtpForAbha,
abhaCardAlreadyExists, enterABHANumber, enterABHAAddress, enterAadhaarNumber,
enterMobileNumber, enterCorrectAuthIdForAuthMode, abhaAddressFound,
searchAndDownloadAbha, abhaSearchMode, verifyAbha, issueInAbhaCard,
fileUploadedSuccessfully, verifyMobileOtp, enterMobileOtp, verify,
abhaNumberAlreadyWith) are still in English; replace each English value with the
appropriate Assamese translation so the UI is consistent, or if leaving them in
English is intentional for a staged rollout, add a clear TODO comment next to
each key indicating why and when the Assamese translations will be added. Ensure
you update the exact JSON entries for those keys (matching the key names above)
and keep JSON syntax valid.

Comment thread src/assets/Hindi.json
Comment on lines +1727 to +1745
"enterMobileNumberToBeLinkedWithAbha": "Enter Phone number to be linked with ABHA",
"doYouWantToVerifyMobileOtpForAbha": "Your provided mobile number is not linked with Aadhaar, Do you want to verify it?",
"abhaCardAlreadyExists": "ABHA already exists for the Aadhaar Number",
"enterABHANumber": "Please Enter ABHA Number",
"enterABHAAddress": "Please Enter ABHA Address",
"enterAadhaarNumber": "Please Enter Aadhaar Number",
"enterMobileNumber": "Please Enter Mobile Number",
"enterCorrectAuthIdForAuthMode": "Please Enter correct Authentication ID for choosen AuthMode",
"abhaAddressFound" : "ABHA Address Found:",
"searchAndDownloadAbha": "Search and Download ABHA",
"abhaSearchMode": "ABHA Search Mode*",
"verifyAbha": "Verify ABHA",
"issueInAbhaCard": "Issue in printing ABHA Card",
"fileUploadedSuccessfully": "File Uploaded successfully",
"verifyMobileOtp": "Verify Mobile OTP",
"enterMobileOtp": "Enter Mobile OTP",
"verify": "Verify",
"abhaNumberAlreadyWith": "The Abha number is already linked with beneficiary ID - ",
"enterTenDigitMobileNumber": "Enter mobile number"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing Hindi translations for ABHA keys—blocks Hindi user experience.

The new ABHA-related keys contain English text instead of Hindi translations. This is a localization defect that breaks the language experience for Hindi-speaking users.

Examples of untranslated keys:

  • Line 1727: "enterMobileNumberToBeLinkedWithAbha": "Enter Phone number to be linked with ABHA"
  • Line 1728: "doYouWantToVerifyMobileOtpForAbha": "Your provided mobile number is not linked with Aadhaar, Do you want to verify it?"
  • Lines 1729-1745: Similar pattern—all values are in English

Expected: All values should be translated to Hindi (Devanagari script) to match the rest of the file and provide a consistent user experience.

Based on learnings, ensure translations are completed before merging i18n changes to avoid breaking the localized user experience.

Sample Hindi translations needed

For reference, these keys need proper Hindi translations similar to existing patterns in the file. For example:

  • enterMobileNumberToBeLinkedWithAbha → "ABHA से जोड़ने के लिए फोन नंबर दर्ज करें"
  • verify → "सत्यापित करें"

All 19 keys in this section require similar treatment.

🤖 Prompt for AI Agents
In @src/assets/Hindi.json around lines 1727 - 1745, Several ABHA-related
localization entries (e.g., enterMobileNumberToBeLinkedWithAbha,
doYouWantToVerifyMobileOtpForAbha, abhaCardAlreadyExists, enterABHANumber,
enterABHAAddress, enterAadhaarNumber, enterMobileNumber,
enterCorrectAuthIdForAuthMode, abhaAddressFound, searchAndDownloadAbha,
abhaSearchMode, verifyAbha, issueInAbhaCard, fileUploadedSuccessfully,
verifyMobileOtp, enterMobileOtp, verify, abhaNumberAlreadyWith,
enterTenDigitMobileNumber) currently contain English values; replace each value
with the correct Hindi (Devanagari) translation matching the file’s existing
style (for example enterMobileNumberToBeLinkedWithAbha -> "ABHA से जोड़ने के लिए
फोन नंबर दर्ज करें", verify -> "सत्यापित करें") ensuring punctuation and
capitalization follow local conventions, and run a quick lint/validation of the
JSON to confirm no syntax changes were introduced.

@5Amogh
5Amogh merged commit 5c36e8a into main Jan 7, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants